package com.bwda.dsrs.filecenter.controller;

import com.bwda.dsrs.base.centerbase.response.CentreCutPageResponse;
import com.bwda.dsrs.base.centerbase.response.CentreListResponse;
import com.bwda.dsrs.base.centerbase.response.ResponseEntity;
import com.bwda.dsrs.base.util.CopyUtil;
import com.bwda.dsrs.filecenter.domain.BusinessConstants;
import com.bwda.dsrs.filecenter.domain.condition.registerkey.RegisterKeyCondition;
import com.bwda.dsrs.filecenter.domain.exception.BusinessServiceException;
import com.bwda.dsrs.filecenter.domain.form.registerkey.RegisterKeyCreateForm;
import com.bwda.dsrs.filecenter.domain.form.registerkey.RegisterKeyQueryForm;
import com.bwda.dsrs.filecenter.domain.form.registerkey.RegisterKeyUpdateForm;
import com.bwda.dsrs.filecenter.domain.po.application.ApplicationPo;
import com.bwda.dsrs.filecenter.domain.po.keyhistory.KeyHistoryPo;
import com.bwda.dsrs.filecenter.domain.po.keyrule.KeyRulePo;
import com.bwda.dsrs.filecenter.domain.po.registerkey.RegisterKeyPo;
import com.bwda.dsrs.filecenter.domain.vo.registerkey.RegisterKeyVo;
import com.bwda.dsrs.filecenter.service.ApplicationService;
import com.bwda.dsrs.filecenter.service.KeyHistoryService;
import com.bwda.dsrs.filecenter.service.KeyRuleService;
import com.bwda.dsrs.filecenter.service.RegisterKeyService;
import com.bwda.dsrs.filecenter.util.PasswordBuilder;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang.math.RandomUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
/**
 * @author Administrator
 */
@RestController
@RequestMapping("/b/registerkey")
@Api(value = "/b/registerkey", tags = "秘钥注册管理")
public class RegisterKeyController extends BaseController {

	@Autowired
	private RegisterKeyService registerKeyService;
	@Autowired
	private KeyRuleService keyRuleService;
	@Autowired
	private ApplicationService  applicationService;
	@Autowired
	private KeyHistoryService keyHistoryService;

	@ApiOperation(value = "查询秘钥注册管理",notes = "查询秘钥注册管理",httpMethod = "GET")
	@RequestMapping(value = "/query", method = {RequestMethod.GET, RequestMethod.POST})
	public ResponseEntity<RegisterKeyVo> query(@ApiParam(value = "注册秘钥id", required = true)@RequestParam Integer registerKeyId) throws BusinessServiceException {
		RegisterKeyPo po = registerKeyService.queryWithValid(registerKeyId);
		RegisterKeyVo vo = CopyUtil.transfer(po, RegisterKeyVo.class);
		return getSuccessResult(vo);
	}

	@ApiOperation(value = "查询秘钥注册管理数量",notes = "查询秘钥注册管理数量",httpMethod = "GET")
	@RequestMapping(value = "/queryCount", method = {RequestMethod.GET, RequestMethod.POST})
	public ResponseEntity<Integer> queryCount(@ModelAttribute@Valid RegisterKeyQueryForm form) throws BusinessServiceException {
		RegisterKeyCondition condition = this.getConditionByQueryForm(form);
		int count = registerKeyService.queryCount(condition);
		return getSuccessResult(count);
	}

	@ApiOperation(value = "查询秘钥注册管理列表",notes = "查询秘钥注册管理列表",httpMethod = "GET")
	@RequestMapping(value = "/queryList", method = {RequestMethod.GET, RequestMethod.POST})
	public ResponseEntity<CentreListResponse<RegisterKeyVo>> queryList(@ModelAttribute@Valid RegisterKeyQueryForm form) throws BusinessServiceException {
		RegisterKeyCondition condition = this.getConditionByQueryForm(form);
		List<RegisterKeyPo> poList = registerKeyService.queryList(condition);
		List<RegisterKeyVo> voList = CopyUtil.transfer(poList, RegisterKeyVo.class);
		return getSuccessResult(getListResponse(voList));
	}

	@ApiOperation(value = "查询秘钥注册管理列表(带分页)",notes = "查询秘钥注册管理列表(带分页)",httpMethod = "GET")
	@RequestMapping(value = "/queryPageList", method = {RequestMethod.GET, RequestMethod.POST})
	public ResponseEntity<CentreCutPageResponse<RegisterKeyVo>> queryPageList(@ModelAttribute@Valid RegisterKeyQueryForm form) throws BusinessServiceException {
		RegisterKeyCondition condition = this.getConditionByQueryForm(form);
		List<RegisterKeyVo> voList = new ArrayList<>();
		List<RegisterKeyVo> voLists = new ArrayList<>();
		condition.setDelFlag(BusinessConstants.NumberConstant.ZERO);
		int count = registerKeyService.queryCount(condition);
		if (count > 0) {
			List<RegisterKeyPo> poList = registerKeyService.queryList(condition);
			voList = CopyUtil.transfer(poList, RegisterKeyVo.class);
			for(RegisterKeyVo registerKeyVo:voList){
				//应用系统id
				Integer appId = registerKeyVo.getAppId();
				ApplicationPo applicationPo = applicationService.query(appId);
				//应用系统名称
				String appName = applicationPo.getAppName();
				//密钥规则id
				Integer keyRuleId = registerKeyVo.getKeyRuleId();
				KeyRulePo keyRulePo=keyRuleService.query(keyRuleId);
				String ruleName = keyRulePo.getRuleName();
				registerKeyVo.setAppName(appName);
				registerKeyVo.setRuleName(ruleName);
				voLists.add(registerKeyVo);
			}
		}
		return getSuccessResult(getPageResponse(form, count, voLists));
	}

	@ApiOperation(value = "新增秘钥注册管理",notes = "新增秘钥注册管理",httpMethod = "POST")
	@RequestMapping(value = "/add", method = {RequestMethod.GET, RequestMethod.POST})
	public ResponseEntity<RegisterKeyVo> add(@ModelAttribute@Valid RegisterKeyCreateForm form) throws BusinessServiceException {
		RegisterKeyPo po = CopyUtil.transfer(form, RegisterKeyPo.class);

		//验证输入秘钥-场景-code名称是否已存在
		int count = registerKeyService.countByTaskCode(po);
		if (count > 0) {
			return getFailResult("此编码已经存在");
		}
        //如果选择了默认，则进行验证
		if(po.getDefaultLabel() == 1){
            //验证应用系统是否已经包含默认秘钥，存在的话，将不再保存
            int countDefault = registerKeyService.countByDefault(po.getAppId());
            if (countDefault >= 1) {
                return getFailResult("此应用已存在默认秘钥");
            }
        }


//		po.setRegisterKeyId(RandomUtils.nextInt());
		//默认未删除
		po.setDelFlag(0);
		po.setCreateTime(new Date());
		po.setUpdateTime(new Date());
		//秘钥提前提醒天数,默认3天
		po.setWarnDays(3);
		//场景编号(默认0全部，以系统编号开头，不可修改)
		//生效时间
		po.setEffectiveTime(new Date());
		Date failureTime = getFailureTime(po.getValiddays());
		po.setFailureTime(failureTime);
		//秘钥规则ID
		Integer keyRuleId = po.getKeyRuleId();
		KeyRulePo keyRulePo = keyRuleService.query(keyRuleId);
		//生成随机密钥
		String pwd = createPwd(keyRulePo);
		//版本
		//得到long类型当前时间
		long l = System.currentTimeMillis();
       //new日期对象
		Date date = new Date(l);
		//转换提日期输出格式
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
		String time = dateFormat.format(date);
		po.setCurrentVersion("V"+time);
		//生成的秘钥
		po.setSecretKey(pwd);
		registerKeyService.insert(po);
		RegisterKeyVo vo = CopyUtil.transfer(po, RegisterKeyVo.class);
		return getSuccessResult(vo);
	}

	@ApiOperation(value = "修改秘钥注册管理",notes = "修改秘钥注册管理",httpMethod = "POST")
	@RequestMapping(value = "/update", method = {RequestMethod.GET, RequestMethod.POST})
	public ResponseEntity update(@ModelAttribute@Valid RegisterKeyUpdateForm form) throws BusinessServiceException {
		RegisterKeyPo po = CopyUtil.transfer(form, RegisterKeyPo.class);

		/**
		 * 验证秘钥-场景-code名称是否已存在
		 */
		int count = registerKeyService.countByTaskCode(po);
		if (count > 0) {
			return getFailResult("此编码已经存在");
		}

		//获取注册密钥Id
		Integer registerKeyId = po.getRegisterKeyId();
		RegisterKeyPo registerKey = registerKeyService.query(registerKeyId);
		if(registerKey!=null){
			//获取更新密钥前生效时间
			Date effectiveTime = registerKey.getEffectiveTime();
			//获取更新密钥前失效时间
			Date failureTime = registerKey.getFailureTime();
			//获取更新密钥之前的版本号
			String currentVersion = registerKey.getCurrentVersion();
			//获取更新密钥之前的应用系统id
			Integer appId = registerKey.getAppId();
			ApplicationPo applicationPo = applicationService.query(appId);
			String appCode = null;
			if(applicationPo!=null){
				//应用系统编码
				appCode = applicationPo.getAppCode();
			}
			//生成密钥
			String secretKey = registerKey.getSecretKey();
			//密钥规则id
			Integer keyRuleId = registerKey.getKeyRuleId();
			KeyRulePo keyRulePo= keyRuleService.query(keyRuleId);
			//生成随机密钥
			String pwd = createPwd(keyRulePo);
			//修改时间
			registerKey.setUpdateTime(new Date());
			//更新最新生效时间
			registerKey.setEffectiveTime(new Date());
			//更新最新失效时间
			Date failureTimes = getFailureTime(registerKey.getValiddays());
			//预计失效时间
			registerKey.setFailureTime(failureTimes);
			registerKey.setDelFlag(0);
			//更新秘钥最新的秘钥
			registerKey.setSecretKey(pwd);
            //历史密钥
            KeyHistoryPo keyHistoryPo = new KeyHistoryPo();
            keyHistoryPo.setRegisterKeyId(registerKey.getRegisterKeyId());
            keyHistoryPo.setRegisterKeyName(registerKey.getRegisterKeyName());
            keyHistoryPo.setEffectiveTime(effectiveTime);
            keyHistoryPo.setFailureTime(failureTime);
            keyHistoryPo.setAppId(appId);
            //更新方式0自动更新1手动更新
            keyHistoryPo.setUpdateType(0);
            keyHistoryPo.setAppCode(appCode);
            keyHistoryPo.setSecretKey(secretKey);
            keyHistoryPo.setCreateTime(new Date());
            keyHistoryPo.setSecretKeyInfo(pwd);
			//更新密钥之前先查询历史密钥表数据是否存在数据，如果存在
            List<KeyHistoryPo>  keyHistory = keyHistoryService.queryList(registerKeyId);
            if(keyHistory!=null && keyHistory.size()>0){
            	//版本号
				String  version = makeVersion(currentVersion);
				registerKey.setCurrentVersion(version);
				keyHistoryPo.setKeyVersion(currentVersion);
            }else{
                //历史密钥表没版本  密钥注册表版本号+1
                registerKey.setCurrentVersion(currentVersion+"_1");
                keyHistoryPo.setKeyVersion(currentVersion);
            }
			registerKeyService.update(registerKey);
			keyHistoryService.insert(keyHistoryPo);
		}
		return getSuccessResult();
	}

	@ApiOperation(value = "删除秘钥注册管理",notes = "删除秘钥注册管理",httpMethod = "POST")
	@RequestMapping(value = "/delete", method = {RequestMethod.GET, RequestMethod.POST})
	public ResponseEntity delete(@ApiParam(value = "注册秘钥id", required = true)@RequestParam List<Integer> registerKeyId) throws BusinessServiceException {
		logger.info("删除秘钥规则");
		//支持批量
		registerKeyId.forEach(integer -> {
			try {
				registerKeyService.delete(integer);
			} catch (BusinessServiceException e) {
				e.printStackTrace();
			}
		});
		return getSuccessResult();
	}

	/**
	 * RegisterKeyQueryForm转换为RegisterKeyCondition
	 *
	 * @param form
	 * @return
	 */
	private RegisterKeyCondition getConditionByQueryForm(RegisterKeyQueryForm form) {
		RegisterKeyCondition condition = CopyUtil.transfer(form, RegisterKeyCondition.class);
		return condition;
	}

	/**
	 * 获取系统当前时间，再当前时间上加有效期天数的时间
	 */
	private Date getFailureTime(Integer validDays){
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.DATE,validDays);
		Date date = cal.getTime();
		return date;
	}

    /**
     * 版本号叠加
     */
    private String makeVersion(String currentVersion){
        String[] versions = currentVersion.split("_");
        //获取版本号最后一位数
		//获取版本号下划线前的数值
		String version= versions[0];
        String versionCode = versions[1];
        //叠加
        int  i = 1;
        //叠加的新值
        String code= String.valueOf(Integer.parseInt(versionCode)+i);
        return version+"_"+ code;
    }

	/**
	 * 生成随机密钥
	 * @param keyRulePo
	 * @return
	 */
	private String createPwd(KeyRulePo keyRulePo){
		Integer fixedLength = null;
		Integer minLength = null;
		Integer maxLength = null;
		Integer hasLetter = null;
		Integer hasNumber= null;
		Integer hasCharacter= null;
		Integer length;
		String  createPwd = null;
		boolean includeLetter = true;
		boolean includeNumber = true;
		boolean includeSpecial = true;
		boolean includeCapital = true;
		if(keyRulePo!=null){
			//固定长度
			fixedLength = keyRulePo.getFixedLength();
			//最小长度
			minLength = keyRulePo.getMinLength();
			//最大长度
			maxLength = keyRulePo.getMaxLength();
			//是否含字母0包含1不包含
			hasLetter = keyRulePo.getHasLetter();
			//是否含数字0包含1不包含
			hasNumber = keyRulePo.getHasNumber();
			//是否含符号0包含1不包含
			hasCharacter = keyRulePo.getHasCharacter();
		}
		if(hasNumber>0){
			includeNumber = false;
		}
		if(hasLetter>0){
			includeLetter = false;
			includeCapital = false;
		}
		if(hasCharacter>0){
			includeSpecial = false;
		}
		if(maxLength==null){
			maxLength=0;
		}
		if(minLength==null){
			minLength=0;
		}
		if(fixedLength==null){
			fixedLength=0;
		}
		if(fixedLength>0){
			length = fixedLength;
			createPwd = PasswordBuilder.createPwd(length,maxLength,includeLetter, includeNumber, includeSpecial,includeCapital);
		}
		if(minLength>0 && maxLength > 0){
			length = minLength;
			createPwd = PasswordBuilder.createPwd(length,maxLength,includeLetter, includeNumber, includeSpecial,includeCapital);
		}
		return createPwd;
	}
}